<!DOCTYPE html>
<!-- saved from url=(0052)http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="author" content="Clinton Begin">
    <meta name="author" content="Nan Lei">
    <meta name="author" content="Dongxu Wang">
    <meta name="Date-Revision-yyyymmdd" content="20160517">
    <meta http-equiv="Content-Language" content="zh">
    <title>mybatis – MyBatis 3 | 动态 SQL</title>
    <link rel="stylesheet" href="./mybatis – MyBatis 3 _ 动态 SQL_files/apache-maven-fluido-1.5.min.css">
    <link rel="stylesheet" href="./mybatis – MyBatis 3 _ 动态 SQL_files/site.css">
    <link rel="stylesheet" href="./mybatis – MyBatis 3 _ 动态 SQL_files/print.css" media="print">

      
    <script type="text/javascript" src="./mybatis – MyBatis 3 _ 动态 SQL_files/apache-maven-fluido-1.5.min.js"></script>

                      </head>
        <body class="topBarDisabled">
          
        
    
        <div class="container-fluid">
          <div id="banner">
        <div class="pull-left">
                                <div id="bannerLeft">
                <h2>mybatis</h2>
                </div>
                      </div>
        <div class="pull-right">                                <a href="http://www.mybatis.org/" id="bannerRight" title="MyBatis logo">
                                                                                        <img src="./mybatis – MyBatis 3 _ 动态 SQL_files/mybatis-logo.png" alt="MyBatis logo">
                </a>
      </div>
        <div class="clear"><hr></div>
      </div>

      <div id="breadcrumbs">
        <ul class="breadcrumb">
              
                  <li id="publishDate">最近更新: 17 五月 2016
                      <span class="divider">|</span>
                   </li>
                  <li id="projectVersion">版本: 3.4.1-SNAPSHOT
                      </li>
                      
              
      
                            </ul>
      </div>

            
      <div class="row-fluid">
        <div id="leftColumn" class="span2">
          <div class="well sidebar-nav">
              
                <ul class="nav nav-list">
                    <li class="nav-header">参考文档</li>
                              
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/index.html" title="简介">
          <span class="none"></span>
        简介</a>
            </li>
                
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/getting-started.html" title="入门">
          <span class="none"></span>
        入门</a>
            </li>
                                                                                                                                                                                                                  
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/configuration.html" title="XML配置">
          <span class="icon-chevron-right"></span>
        XML配置</a>
                  </li>
                                                                                                                                                            
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html" title="XML映射文件">
          <span class="icon-chevron-right"></span>
        XML映射文件</a>
                  </li>
                
      <li class="active">
  
            <a href="http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html#"><span class="none"></span>动态SQL</a>
          </li>
                                                                                    
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/java-api.html" title="Java API">
          <span class="icon-chevron-right"></span>
        Java API</a>
                  </li>
                
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/statement-builders.html" title="SQL语句构建器">
          <span class="none"></span>
        SQL语句构建器</a>
            </li>
                
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/logging.html" title="日志">
          <span class="none"></span>
        日志</a>
            </li>
                              <li class="nav-header">项目文档</li>
                                                                                                                                                                                                                                                                                      
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/project-info.html" title="项目信息">
          <span class="icon-chevron-right"></span>
        项目信息</a>
                  </li>
                                                                                                                                                                                                                                                                                          
      <li>
  
                          <a href="http://www.mybatis.org/mybatis-3/zh/project-reports.html" title="项目报表">
          <span class="icon-chevron-right"></span>
        项目报表</a>
                  </li>
            </ul>
              
                
          <hr>

           <div id="poweredBy">
                            <div class="clear"></div>
                            <div class="clear"></div>
                            <div class="clear"></div>
                            <div class="clear"></div>
                             <a href="http://maven.apache.org/" title="构建依靠 Maven" class="poweredBy">
        <img class="builtBy" alt="构建依靠 Maven" src="./mybatis – MyBatis 3 _ 动态 SQL_files/maven-feather.png">
      </a>
                  </div>
          </div>
        </div>
        
                
        <div id="bodyColumn" class="span10">
                                  
            

  
    <div class="section">
<h2><a name="a_SQL"></a>动态 SQL</h2>
      
<p>MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验，你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格，还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。</p>
      
<p>通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。</p>
      
<p>动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。</p>
      
<ul>
        
<li>if</li>
        
<li>choose (when, otherwise)</li>
        
<li>trim (where, set)</li>
        
<li>foreach</li>
      </ul>
      <a name="if"></a>
<div class="section" id="if">
<h3><a name="if"></a>if</h3>
        
<p>动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。比如:</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"findActiveBlogWithTitleLike"</span><span class="pln">
     </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"Blog"</span><span class="tag">&gt;</span><span class="pln">
  SELECT * FROM BLOG 
  WHERE state = ‘ACTIVE’ 
  </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"title != null"</span><span class="tag">&gt;</span><span class="pln">
    AND title like #{title}
  </span><span class="tag">&lt;/if&gt;</span><span class="pln">
</span><span class="tag">&lt;/select&gt;</span></pre></div>
        
<p>这条语句提供了一个可选的文本查找类型的功能。如果没有传入“title”，那么所有处于“ACTIVE”状态的BLOG都会返回；反之若传入了“title”，那么就会把模糊查找“title”内容的BLOG结果返回（就这个例子而言，细心的读者会发现其中的参数值是可以包含一些掩码或通配符的）。</p>
        
<p>如果想可选地通过“title”和“author”两个条件搜索该怎么办呢？首先，改变语句的名称让它更具实际意义；然后只要加入另一个条件即可。</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"findActiveBlogLike"</span><span class="pln">
     </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"Blog"</span><span class="tag">&gt;</span><span class="pln">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’ 
  </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"title != null"</span><span class="tag">&gt;</span><span class="pln">
    AND title like #{title}
  </span><span class="tag">&lt;/if&gt;</span><span class="pln">
  </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"author != null and author.name != null"</span><span class="tag">&gt;</span><span class="pln">
    AND author_name like #{author.name}
  </span><span class="tag">&lt;/if&gt;</span><span class="pln">
</span><span class="tag">&lt;/select&gt;</span></pre></div>
      </div>
      <a name="chooseWhenOtherwise"></a>
<div class="section" id="chooseWhenOtherwise">
<h3><a name="choose_when_otherwise"></a>choose, when, otherwise</h3>
        
<p>有些时候，我们不想用到所有的条件语句，而只想从中择其一二。针对这种情况，MyBatis 提供了 choose 元素，它有点像 Java 中的 switch 语句。</p>
        
<p>还是上面的例子，但是这次变为提供了“title”就按“title”查找，提供了“author”就按“author”查找，若两者都没有提供，就返回所有符合条件的BLOG（实际情况可能是由管理员按一定策略选出BLOG列表，而不是返回大量无意义的随机结果）。</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"findActiveBlogLike"</span><span class="pln">
     </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"Blog"</span><span class="tag">&gt;</span><span class="pln">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  </span><span class="tag">&lt;choose&gt;</span><span class="pln">
    </span><span class="tag">&lt;when</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"title != null"</span><span class="tag">&gt;</span><span class="pln">
      AND title like #{title}
    </span><span class="tag">&lt;/when&gt;</span><span class="pln">
    </span><span class="tag">&lt;when</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"author != null and author.name != null"</span><span class="tag">&gt;</span><span class="pln">
      AND author_name like #{author.name}
    </span><span class="tag">&lt;/when&gt;</span><span class="pln">
    </span><span class="tag">&lt;otherwise&gt;</span><span class="pln">
      AND featured = 1
    </span><span class="tag">&lt;/otherwise&gt;</span><span class="pln">
  </span><span class="tag">&lt;/choose&gt;</span><span class="pln">
</span><span class="tag">&lt;/select&gt;</span></pre></div>
      </div>
      <a name="trimWhereSet"></a>
<div class="section" id="trimWhereSet">
<h3><a name="trim_where_set"></a>trim, where, set</h3>
        
<p>前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。现在考虑回到“if”示例，这次我们将“ACTIVE = 1”也设置成动态的条件，看看会发生什么。</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"findActiveBlogLike"</span><span class="pln">
     </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"Blog"</span><span class="tag">&gt;</span><span class="pln">
  SELECT * FROM BLOG 
  WHERE 
  </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"state != null"</span><span class="tag">&gt;</span><span class="pln">
    state = #{state}
  </span><span class="tag">&lt;/if&gt;</span><span class="pln"> 
  </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"title != null"</span><span class="tag">&gt;</span><span class="pln">
    AND title like #{title}
  </span><span class="tag">&lt;/if&gt;</span><span class="pln">
  </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"author != null and author.name != null"</span><span class="tag">&gt;</span><span class="pln">
    AND author_name like #{author.name}
  </span><span class="tag">&lt;/if&gt;</span><span class="pln">
</span><span class="tag">&lt;/select&gt;</span></pre></div>
        
<p>如果这些条件没有一个能匹配上将会怎样？最终这条 SQL 会变成这样：</p>
        
<div class="source"><pre class="prettyprint"><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM BLOG
WHERE</span></pre></div>
        
<p>这会导致查询失败。如果仅仅第二个条件匹配又会怎样？这条 SQL 最终会是这样:
        </p>
        
<div class="source"><pre class="prettyprint"><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM BLOG
WHERE 
AND title like </span><span class="pun">‘</span><span class="pln">someTitle</span><span class="pun">’</span></pre></div>
        
<p>这个查询也会失败。这个问题不能简单的用条件句式来解决，如果你也曾经被迫这样写过，那么你很可能从此以后都不想再这样去写了。</p>
        
<p>MyBatis 有一个简单的处理，这在90%的情况下都会有用。而在不能使用的地方，你可以自定义处理方式来令其正常工作。一处简单的修改就能得到想要的效果：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"findActiveBlogLike"</span><span class="pln">
     </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"Blog"</span><span class="tag">&gt;</span><span class="pln">
  SELECT * FROM BLOG 
  </span><span class="tag">&lt;where&gt;</span><span class="pln"> 
    </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"state != null"</span><span class="tag">&gt;</span><span class="pln">
         state = #{state}
    </span><span class="tag">&lt;/if&gt;</span><span class="pln"> 
    </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"title != null"</span><span class="tag">&gt;</span><span class="pln">
        AND title like #{title}
    </span><span class="tag">&lt;/if&gt;</span><span class="pln">
    </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"author != null and author.name != null"</span><span class="tag">&gt;</span><span class="pln">
        AND author_name like #{author.name}
    </span><span class="tag">&lt;/if&gt;</span><span class="pln">
  </span><span class="tag">&lt;/where&gt;</span><span class="pln">
</span><span class="tag">&lt;/select&gt;</span></pre></div>
        
<p>where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且，若最后的内容是“AND”或“OR”开头的，where 元素也知道如何将他们去除。</p>
        
<p>如果 where 元素没有按正常套路出牌，我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如，和 where 元素等价的自定义 trim 元素为：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;trim</span><span class="pln"> </span><span class="atn">prefix</span><span class="pun">=</span><span class="atv">"WHERE"</span><span class="pln"> </span><span class="atn">prefixOverrides</span><span class="pun">=</span><span class="atv">"AND |OR "</span><span class="tag">&gt;</span><span class="pln">
  ... 
</span><span class="tag">&lt;/trim&gt;</span></pre></div>
        
<p>prefixOverrides 属性会忽略通过管道分隔的文本序列（注意此例中的空格也是必要的）。它带来的结果就是所有在 prefixOverrides 属性中指定的内容将被移除，并且插入 prefix 属性中指定的内容。</p>
        
<p>类似的用于动态更新语句的解决方案叫做 set。set 元素可以被用于动态包含需要更新的列，而舍去其他的。比如：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;update</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"updateAuthorIfNecessary"</span><span class="tag">&gt;</span><span class="pln">
  update Author
    </span><span class="tag">&lt;set&gt;</span><span class="pln">
      </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"username != null"</span><span class="tag">&gt;</span><span class="pln">username=#{username},</span><span class="tag">&lt;/if&gt;</span><span class="pln">
      </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"password != null"</span><span class="tag">&gt;</span><span class="pln">password=#{password},</span><span class="tag">&lt;/if&gt;</span><span class="pln">
      </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"email != null"</span><span class="tag">&gt;</span><span class="pln">email=#{email},</span><span class="tag">&lt;/if&gt;</span><span class="pln">
      </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"bio != null"</span><span class="tag">&gt;</span><span class="pln">bio=#{bio}</span><span class="tag">&lt;/if&gt;</span><span class="pln">
    </span><span class="tag">&lt;/set&gt;</span><span class="pln">
  where id=#{id}
</span><span class="tag">&lt;/update&gt;</span></pre></div>
        
<p>这里，set 元素会动态前置 SET 关键字，同时也会消除无关的逗号，因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号。</p>
        
<p>若你对等价的自定义 trim 元素的样子感兴趣，那这就应该是它的真面目：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;trim</span><span class="pln"> </span><span class="atn">prefix</span><span class="pun">=</span><span class="atv">"SET"</span><span class="pln"> </span><span class="atn">suffixOverrides</span><span class="pun">=</span><span class="atv">","</span><span class="tag">&gt;</span><span class="pln">
  ...
</span><span class="tag">&lt;/trim&gt;</span></pre></div>
        
<p>注意这里我们忽略的是后缀中的值，而又一次附加了前缀中的值。</p>
      </div>
      
<div class="section">
<h3><a name="foreach"></a>foreach</h3>
        
<p>动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历，通常是在构建 IN 条件语句的时候。比如：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"selectPostIn"</span><span class="pln"> </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"domain.blog.Post"</span><span class="tag">&gt;</span><span class="pln">
  SELECT *
  FROM POST P
  WHERE ID in
  </span><span class="tag">&lt;foreach</span><span class="pln"> </span><span class="atn">item</span><span class="pun">=</span><span class="atv">"item"</span><span class="pln"> </span><span class="atn">index</span><span class="pun">=</span><span class="atv">"index"</span><span class="pln"> </span><span class="atn">collection</span><span class="pun">=</span><span class="atv">"list"</span><span class="pln">
      </span><span class="atn">open</span><span class="pun">=</span><span class="atv">"("</span><span class="pln"> </span><span class="atn">separator</span><span class="pun">=</span><span class="atv">","</span><span class="pln"> </span><span class="atn">close</span><span class="pun">=</span><span class="atv">")"</span><span class="tag">&gt;</span><span class="pln">
        #{item}
  </span><span class="tag">&lt;/foreach&gt;</span><span class="pln">
</span><span class="tag">&lt;/select&gt;</span></pre></div>
        
<p>foreach 元素的功能是非常强大的，它允许你指定一个集合，声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串以及在迭代中间放置分隔符。这个元素是很智能的，因此它不会偶然地附加多余的分隔符。</p>
        
<p><span class="label important">注意</span> 你可以将任何可迭代对象（如列表、集合等）和任何的字典或者数组对象传递给foreach作为集合参数。当使用可迭代对象或者数组时，index是当前迭代的次数，item的值是本次迭代获取的元素。当使用字典（或者Map.Entry对象的集合）时，index是键，item是值。</p>
        
<p>到此我们已经完成了涉及 XML 配置文件和 XML 映射文件的讨论。下一部分将详细探讨 Java API，这样才能从已创建的映射中获取最大利益。</p>
      </div>
      
<div class="section">
<h3><a name="bind"></a>bind</h3>
        
<p><tt>bind</tt> 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"selectBlogsLike"</span><span class="pln"> </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"Blog"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;bind</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"pattern"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"'%' + _parameter.getTitle() + '%'"</span><span class="pln"> </span><span class="tag">/&gt;</span><span class="pln">
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</span><span class="tag">&lt;/select&gt;</span></pre></div>
      </div>
      
<div class="section">
<h3><a name="Multi-db_vendor_support"></a>Multi-db vendor support</h3>
        
<p>一个配置了“_databaseId”变量的 databaseIdProvider 对于动态代码来说是可用的，这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;insert</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"insert"</span><span class="tag">&gt;</span><span class="pln">
  </span><span class="tag">&lt;selectKey</span><span class="pln"> </span><span class="atn">keyProperty</span><span class="pun">=</span><span class="atv">"id"</span><span class="pln"> </span><span class="atn">resultType</span><span class="pun">=</span><span class="atv">"int"</span><span class="pln"> </span><span class="atn">order</span><span class="pun">=</span><span class="atv">"BEFORE"</span><span class="tag">&gt;</span><span class="pln">
    </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"_databaseId == 'oracle'"</span><span class="tag">&gt;</span><span class="pln">
      select seq_users.nextval from dual
    </span><span class="tag">&lt;/if&gt;</span><span class="pln">
    </span><span class="tag">&lt;if</span><span class="pln"> </span><span class="atn">test</span><span class="pun">=</span><span class="atv">"_databaseId == 'db2'"</span><span class="tag">&gt;</span><span class="pln">
      select nextval for seq_users from sysibm.sysdummy1"
    </span><span class="tag">&lt;/if&gt;</span><span class="pln">
  </span><span class="tag">&lt;/selectKey&gt;</span><span class="pln">
  insert into users values (#{id}, #{name})
</span><span class="tag">&lt;/insert&gt;</span></pre></div>
      </div>
      
<div class="section">
<h3><a name="a_SQL_"></a>动态 SQL 中可插拔的脚本语言</h3>
        
<p>MyBatis 从 3.2 开始支持可插拔的脚本语言，因此你可以在插入一种语言的驱动（language driver）之后来写基于这种语言的动态 SQL 查询。</p>
        
<p>可以通过实现下面接口的方式来插入一种语言：</p>
        
<div class="source"><pre class="prettyprint"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">LanguageDriver</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">ParameterHandler</span><span class="pln"> createParameterHandler</span><span class="pun">(</span><span class="typ">MappedStatement</span><span class="pln"> mappedStatement</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Object</span><span class="pln"> parameterObject</span><span class="pun">,</span><span class="pln"> </span><span class="typ">BoundSql</span><span class="pln"> boundSql</span><span class="pun">);</span><span class="pln">
  </span><span class="typ">SqlSource</span><span class="pln"> createSqlSource</span><span class="pun">(</span><span class="typ">Configuration</span><span class="pln"> configuration</span><span class="pun">,</span><span class="pln"> </span><span class="typ">XNode</span><span class="pln"> script</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Class</span><span class="pun">&lt;?&gt;</span><span class="pln"> parameterType</span><span class="pun">);</span><span class="pln">
  </span><span class="typ">SqlSource</span><span class="pln"> createSqlSource</span><span class="pun">(</span><span class="typ">Configuration</span><span class="pln"> configuration</span><span class="pun">,</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> script</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Class</span><span class="pun">&lt;?&gt;</span><span class="pln"> parameterType</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre></div>
        
<p>一旦有了自定义的语言驱动，你就可以在 mybatis-config.xml 文件中将它设置为默认语言：</p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;typeAliases&gt;</span><span class="pln">
  </span><span class="tag">&lt;typeAlias</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"org.sample.MyLanguageDriver"</span><span class="pln"> </span><span class="atn">alias</span><span class="pun">=</span><span class="atv">"myLanguage"</span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/typeAliases&gt;</span><span class="pln">
</span><span class="tag">&lt;settings&gt;</span><span class="pln">
  </span><span class="tag">&lt;setting</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"defaultScriptingLanguage"</span><span class="pln"> </span><span class="atn">value</span><span class="pun">=</span><span class="atv">"myLanguage"</span><span class="tag">/&gt;</span><span class="pln">
</span><span class="tag">&lt;/settings&gt;</span></pre></div>
        
<p>除了设置默认语言，你也可以针对特殊的语句指定特定语言，这可以通过如下的 <tt>lang</tt> 属性来完成：
        </p>
        
<div class="source"><pre class="prettyprint"><span class="tag">&lt;select</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"selectBlog"</span><span class="pln"> </span><span class="atn">lang</span><span class="pun">=</span><span class="atv">"myLanguage"</span><span class="tag">&gt;</span><span class="pln">
  SELECT * FROM BLOG
</span><span class="tag">&lt;/select&gt;</span></pre></div>
        
<p>或者在你正在使用的映射中加上注解 <tt>@Lang</tt> 来完成：</p>
        
<div class="source"><pre class="prettyprint"><span class="kwd">public</span><span class="pln"> </span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">Mapper</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="lit">@Lang</span><span class="pun">(</span><span class="typ">MyLanguageDriver</span><span class="pun">.</span><span class="kwd">class</span><span class="pun">)</span><span class="pln">
  </span><span class="lit">@Select</span><span class="pun">(</span><span class="str">"SELECT * FROM BLOG"</span><span class="pun">)</span><span class="pln">
  </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">Blog</span><span class="pun">&gt;</span><span class="pln"> selectBlog</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre></div>

        
<p><span class="label important">注意</span> 可以将 Apache Velocity 作为动态语言来使用，更多细节请参考 MyBatis-Velocity 项目。</p>

        
<p>你前面看到的所有 xml 标签都是默认 MyBatis 语言提供的，它是由别名为 <tt>xml</tt> 语言驱动器 <tt>org.apache.ibatis.scripting.xmltags.XmlLanguageDriver</tt> 驱动的。</p>
      </div>
    </div>
  

                  </div>
            </div>
          </div>

    <hr>

    <footer>
            <div class="container-fluid">
                      <div class="row-fluid">
                                      <p>Copyright ©                    2009–2016
                        <a href="http://www.mybatis.org/">MyBatis.org</a>.
            All rights reserved.    
      </p>
                </div>

        
                </div>
    </footer>
        

</body></html>